package com.uto;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ExpandableListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.uto.backend.ServerResponse;
import com.uto.backend.interfaces.IAppManager;
import com.uto.backend.interfaces.IServerResponse;
import com.uto.frontend.interfaces.IServiceListener;

public class JoinGame extends ExpandableListActivity implements Runnable , OnClickListener{

	private static final long DAY = 1000*60*60*24;

	private static final long WEEK = DAY*7;

	private static final long YEAR = DAY*365;

	private User user;

	private int phase;

	MyExpandableListAdapter mAdapter;

	private ProgressDialog pd;

	private final int IS_OK = 0;
	private final int NOT_OK = 1;

	private final String TAG = "com.uto.JoinGame";

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		user = getIntent().getParcelableExtra("user");

		// Set up our adapter
		mAdapter = new MyExpandableListAdapter();

		phase = 0;
		new Thread(this).start();
		pd = ProgressDialog.show(this, getString(R.string.loading) , getString(R.string.fetching_game_list), true, false);
	}

	public void run() {
		try {
			IAppManager manager = MyServiceConnection.getAppManager();
			if (manager==null){
				Log.v(TAG, "IAppManager is null");
				Toast.makeText(JoinGame.this, "Request Failed Try Again Later1", Toast.LENGTH_LONG).show();
			}
			if (listener==null) {
				Log.v(TAG, "listener is null");
				Toast.makeText(JoinGame.this, "listener is null", Toast.LENGTH_LONG).show();
			}
			else {
				manager.getAviliableGames(listener);
			}
		} catch (Exception e) {
			Log.e(TAG, e.getStackTrace().toString());
			Log.e(TAG, e.toString());
			Log.e(TAG, e.getMessage());
			Log.e(TAG, "problem with the manager!!!");
			Toast.makeText(JoinGame.this, getString(R.string.start_game_fail), Toast.LENGTH_LONG).show();
			finish();
		}
	}

	public class MyExpandableListAdapter extends BaseExpandableListAdapter {

		private ArrayList<String> groups;
		private ArrayList<String[]> children;

		public MyExpandableListAdapter(){
			groups = new ArrayList<String>();
			children = new ArrayList<String[]>();
		}

		public void addGroup(String group, String[] child){
			groups.add(group);
			children.add(child);
		}

		public TextView getGenericView() {
			// Layout parameters for the ExpandableListView
			AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
					ViewGroup.LayoutParams.FILL_PARENT, 64);

			TextView textView = new TextView(JoinGame.this);
			textView.setLayoutParams(lp);
			// Center the text vertically
			textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
			// Set the text starting position
			textView.setPadding(36, 0, 0, 0);
			return textView;
		}



		public Object getChild(int groupPosition, int childPosition) {
			return children.get(groupPosition)[childPosition];
		}

		public long getChildId(int groupPosition, int childPosition) {
			return childPosition;
		}

		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			if (childPosition<groups.get(groupPosition).length()-1){
				TextView view = getGenericView();
				view.setText(children.get(groupPosition)[childPosition]);
				return view;
			}
			else{
				Button button = new Button(JoinGame.this);
				button.setText(getString(R.string.play_this_one));
				button.setContentDescription(children.get(groupPosition)[childPosition]);
				button.setOnClickListener(JoinGame.this);
				return button;
			}

		}

		public int getChildrenCount(int groupPosition) {
			return children.get(groupPosition).length;
		}

		public Object getGroup(int groupPosition) {
			return groups.get(groupPosition);
		}

		public int getGroupCount() {
			return groups.size();
		}

		public long getGroupId(int groupPosition) {
			return groupPosition;
		}

		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			TextView view = getGenericView();
			view.setText(groups.get(groupPosition));
			return view;
		}

		public boolean hasStableIds() {
			return false;
		}

		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return true;
		}


	}

	public void onClick(View v) {
		phase = 1;

		IAppManager manager = MyServiceConnection.getAppManager();
		if (manager==null){
			Log.v(TAG, "IAppManager is null");
			Toast.makeText(JoinGame.this, getString(R.string.start_game_fail), Toast.LENGTH_LONG).show();
			return;
		}

		try {
			manager.joinGame(listener, v.getContentDescription().toString(),user.getUsername());
		} catch (RemoteException e) {
			e.printStackTrace();
			Toast.makeText(JoinGame.this, getString(R.string.start_game_fail), Toast.LENGTH_LONG).show();
			return;
		}
		pd = ProgressDialog.show(JoinGame.this, getString(R.string.starting_game),"");

	}

	private Handler listHandler = new Handler(){
		public void handleMessage(Message msg){

			if (pd!=null && pd.isShowing())
				pd.dismiss();

			if (msg.arg1==NOT_OK){
				String message = (String)msg.obj;
				if (message != null)
					Toast.makeText(JoinGame.this, message, Toast.LENGTH_LONG).show();
				JoinGame.this.finish();
			}

			else{
				setListAdapter(mAdapter);
			}

		}
	};

	private Handler joinHandler = new Handler(){
		public void handleMessage(Message msg){

			if (pd!=null && pd.isShowing())
				pd.dismiss();

			if (msg.arg1==NOT_OK){
				String message = (String)msg.obj;
				if (message != null)
					Toast.makeText(JoinGame.this, message, Toast.LENGTH_LONG).show();
				return;
			}

			else{
				Intent gameIntent = new Intent(JoinGame.this, MapViewOpenStreet.class);
				gameIntent.putExtra("user" , user);
				SharedPreferences settings = getSharedPreferences(UTO.USER_FILE, 0);
				SharedPreferences.Editor editor = settings.edit();
				editor.putBoolean("inGame", true);
				// Commit the edits!
				editor.commit();
				startActivity(gameIntent);

			}

		}
	};

	private final IServiceListener.Stub listener = new IServiceListener.Stub(){

		public void handleMessage(IServerResponse response) {

			Map<String , Object> data = null;
			Message msg = new Message();
			
			Handler hanlder = (phase==0)? listHandler : joinHandler;

			try {
				if (response == null)
				{
					msg.arg1 = NOT_OK;
					hanlder.sendMessage(msg);
					Log.e(TAG, "null response");
					return;
				}

				if (!response.isOk()){

					msg.obj = response.getMessage();
					msg.arg1 = NOT_OK;
					hanlder.sendMessage(msg);
					return;
				}
				data = response.getData();				

			} catch (RemoteException e) {
				hanlder.sendEmptyMessage(NOT_OK);
				Log.e(TAG , e.getMessage());
				e.printStackTrace();
			}

			if (phase==0){
				//build the list of games from the given data
				String str = (String)data.get("games");
				JSONArray array = null;
				try {
					array = new JSONArray(str);


					for (int i=0; i<array.length(); i++){
						String curString = array.getString(i);
						JSONObject curObj = new JSONObject(curString);
						long timePlayed = Long.parseLong(curObj.getString("runningTime"));
						String timePlayedStr = null;
						if (timePlayed<DAY)
							timePlayedStr = getString(R.string.less_than_one_day);
						else if (timePlayed<WEEK)
							timePlayedStr = getString(R.string.less_than_one_week);
						else if (timePlayed<YEAR)
							timePlayedStr = ((int)timePlayed/WEEK) + getString(R.string.weeks);
						else
							timePlayedStr = getString(R.string.more_than_year);

						String playerCount = getString(R.string.player_count) + curObj.getString("numOfPlayers");
						String playerMax = getString(R.string.max_players) + curObj.getString("maxNumOfPlayers");
						String money = getString(R.string.init_money) + curObj.getString("startMoney");
						String key = curObj.getString("key");

						mAdapter.addGroup("game"+(i+1), new String[] {timePlayedStr , playerCount, playerMax , money , key});
					}

				} catch (JSONException e) {
					msg.obj = e.getMessage();
					msg.arg1 = NOT_OK;
					hanlder.sendMessage(msg);
					e.printStackTrace();
				}
			}
			//call the handler to notify that the data is here
			hanlder.sendEmptyMessage(IS_OK);


		}
	};


}
